package lc.com.lcpicturebackend.controller;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lc.com.lcpicturebackend.common.BaseResponse;
import lc.com.lcpicturebackend.common.ResultUtils;
import lc.com.lcpicturebackend.exception.BusinessException;
import lc.com.lcpicturebackend.exception.ErrorCode;
import lc.com.lcpicturebackend.manager.app.PhotoChatClient;
import lc.com.lcpicturebackend.model.dto.chatai.ConversationAddRequest;
import lc.com.lcpicturebackend.model.entity.User;
import lc.com.lcpicturebackend.service.ConversationService;
import lc.com.lcpicturebackend.service.SseService;
import lc.com.lcpicturebackend.service.UserService;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Flux;

import java.io.IOException;

/**
 * ai控制器
 */

@RestController
@CrossOrigin
@RequestMapping("/ai")
public class AIController {
    @Resource
    private PhotoChatClient photoChatClient;

    @Resource
    private UserService userService;

    @Resource
    private ConversationService conversationService;

    @Resource
    private SseService sseService;

    @GetMapping("/simple/dochat")
    public BaseResponse<String> doChat(@RequestParam("query") String query, @RequestParam("chatId") Long chatId) {
        String result = photoChatClient.doChat(query, chatId);
        return ResultUtils.success(result);
    }


    @PostMapping(value = "/simple/dochat/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> doChatDemoSSE(@RequestBody ConversationAddRequest conversationAddRequest,
                                      HttpServletRequest request) {
        if (conversationAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        conversationService.createConversation(conversationAddRequest, loginUser);
        return photoChatClient.doChatDemo(conversationAddRequest.getContent(),
                conversationAddRequest.getConversationId(),
                loginUser);

    }

    /**
     * 返回Flux 对象，并且设置泛型为 ServerSentEvent
     *
     * @param conversationAddRequest
     * @param request
     * @return
     */
    @PostMapping("/simple/dochat/server/sent/event")
    public Flux<ServerSentEvent<String>> doChatDemoServerSentEvent(@RequestBody ConversationAddRequest conversationAddRequest,
                                                                   HttpServletRequest request) {
        if (conversationAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        conversationService.createConversation(conversationAddRequest, loginUser);
        return photoChatClient.doChatDemo(conversationAddRequest.getContent(),
                        conversationAddRequest.getConversationId(),
                        loginUser)
                .map(chunk -> ServerSentEvent.<String>builder()
                        .data(chunk)
                        .build());
    }

    /**
     * 使用SseEmiter,通过 send 方法持续向 SseEmitter 发送消息（有点像 IO 操作）
     *
     * @param conversationAddRequest
     * @param request
     * @return
     */
    @PostMapping("/simple/dochat/sse/emitter")
    public SseEmitter doChatDemoSseEmitter(@RequestBody ConversationAddRequest conversationAddRequest,
                                           HttpServletRequest request) {
        if (conversationAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 创建一个超时时间较长的 SseEmitter
        SseEmitter emitter = new SseEmitter(180000L); // 3分钟超时
        User loginUser = userService.getLoginUser(request);
        conversationService.createConversation(conversationAddRequest, loginUser);
        // 获取 Flux 数据流并直接订阅

        photoChatClient.doChatDemo(conversationAddRequest.getContent(),
                        conversationAddRequest.getConversationId(),
                        loginUser)
                .subscribe(
                        // 处理每条消息
                        chunk -> {
                            try {
                                emitter.send(chunk);
                            } catch (IOException e) {
                                emitter.completeWithError(e);
                            }
                        },
                        // 处理错误
                        emitter::completeWithError,
                        emitter::complete
                );
        return emitter;
    }


    // 原控制器文件
    @PostMapping("/simple/dochat/sse/emitter2")
    public SseEmitter doChatDemoSseEmitter1(@RequestBody ConversationAddRequest conversationAddRequest,
                                           HttpServletRequest request) {
        if (conversationAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 创建一个超时时间较长的 SseEmitter
        SseEmitter emitter = new SseEmitter(180000L); // 3分钟超时
        User loginUser = userService.getLoginUser(request);
        conversationService.createConversation(conversationAddRequest, loginUser);

        // 创建 StringBuilder 用于缓存 Markdown 内容
        StringBuilder markdownBuffer = new StringBuilder();

        photoChatClient.doChatDemo(conversationAddRequest.getContent(),
                        conversationAddRequest.getConversationId(),
                        loginUser)
                .subscribe(
                        // 处理每条消息
                        chunk -> {
                            try {
                                sseService.handleSseMessage(chunk, markdownBuffer, emitter);
                            } catch (IOException e) {
                                emitter.completeWithError(e);
                            }
                        },
                        // 处理错误
                        error -> {
                            try {
                                sseService.handleRemainingContent(markdownBuffer, emitter);
                            } catch (IOException e) {
                                // 忽略发送剩余内容时的错误
                            }
                            emitter.completeWithError(error);
                        },
                        // 完成时的处理
                        () -> {
                            try {
                                sseService.handleRemainingContent(markdownBuffer, emitter);
                                emitter.complete();
                            } catch (IOException e) {
                                emitter.completeWithError(e);
                            }
                        }
                );
        return emitter;
    }
}



